import { defineStore } from 'pinia'
import api from "@/utils/http.js"; //封装请求
const useSocketStore = defineStore(
    'socket',
    {
      state: () => ({
        ws: undefined,
        heartTimeOut: 40000, //监测心跳时间 40秒
        //this.isReConnection = false
        lockReconnect: false, //避免重连
        timerReconnect: undefined,
        timerHeart: undefined,
        timerServerHeart: undefined,
        handClose: false,
        msg: "",
        uid:"",//用户uid
      }),
      getters:{
        getWsState(state){
          return state.ws;
        },
      },
      actions: {
        connection(url,uid){
          if("WebSocket" in window){
            this.createWebSocket(url,uid)
          }
          else{
            console.log("您的浏览器不支持websocket通信")
          }    
        },
      
        //初始化
        createWebSocket(url,uid){
          try{
            this.ws = new WebSocket(url)  // 
            this.uid = uid;
            this.initWebsocket()
            
          }
          catch(e){
            // console.log("catch eeeee=", e)
            this.reConnection()
          }
        },
      
        initWebsocket(){
          let that = this;
          //建立连接
          that.ws.onopen = (e)=>{
           
            //webSocket业务订阅——可以有多个业务
            that.ws.send("hello server");
            // console.log("连接成功",e)
            //连接成功后，需要开启监测心跳
            that.heartCheck()
          }
      
          that.ws.onmessage = (messages)=>{
            let msg = messages.data
            if(msg.includes("{")){
              msg = JSON.parse(msg);
              // console.log(that.uid,msg,"5555")
              if(msg.type === "init"){
                that.bindSocket(msg.data.clientId,that.uid);
              }
            }
            that.msg = msg
  
            //接收到消息后，需要开启监测心跳
            that.heartCheck();
          }
      
        
          that.ws.onerror = (e)=>{       //连不上时onerror 和 onclose 监听同时会捕捉到
            console.log("连接失败")
            // 连失败需要重连
            that.reConnection()
          }
      
          that.ws.onclose = (e)=>{
            console.log("关闭连接")
           
            //是否正常关闭  正常关闭不需要重连， 否则需要重连
            if(!that.handClose){
              that.reConnection()
            }
          }
        },
      
        clearTimer(){
          this.timerReconnect && clearTimeout(this.timerReconnect)
          this.timerHeart && clearTimeout(this.timerHeart)
          this.timerServerHeart && clearTimeout(this.timerServerHeart)
        },
      
        //重连
        reConnection(){
          console.log("重新连接")
          if(this.lockReconnect){
            return
          }
          this.lockReconnect = true
          if(this.timerReconnect) {
            clearTimeout(this.timerReconnect)
          } 
      
          //没连上会一直重连， 设置迟延，避免请求过多
          this.timerReconnect = setTimeout(() => { //setTimeout 到点了执行
            this.connection()
            this.lockReconnect = false
          }, 5000);
          
        },
        
      
        //心跳
        heartCheck(){
          // console.log("监测心跳")
          if(this.timerHeart){
            clearTimeout(this.timerHeart)
          }
      
          // if(this.timerServerHeart){
          //   clearTimeout(this.timerServerHeart)
          // }
      
          this.timerHeart = setTimeout(() => {
            console.log("PING");
            this.ws.send("PING");
      
            // this.timerServerHeart = setTimeout(() => {
            //   // 断了
            //   this.ws.close()
            // }, 5000);
      
            this.lockReconnect = false
          }, this.heartTimeOut); //40秒
      
        },
      
        //发送消息
        sendMsg(data){
          // console.log("发送消息")
          if(this.ws.readyState === WebSocket.OPEN){
            this.ws.send(JSON.stringify(data))
          }
        },
      
        //关闭连接 手动关闭
        closeWs(){
          // console.log("手动关闭ws")
          this.handClose = true
          this.clearTimer()
          this.ws.close()
        },
        //绑定im 即登录im
        bindSocket(clientId,uid){
          api.post("v1/login/chat/chat/bind_user", { clientId: clientId,uid}).then((res) => {});
        },
      }
    })
  
  export default useSocketStore